package com.wocai.jrt.admin.user.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.inject.Inject;
import javax.inject.Named;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vteba.common.exception.BasicException;
import com.vteba.common.exception.ServiceException;
import com.vteba.service.generic.impl.MyBatisServiceImpl;
import com.vteba.tx.jdbc.mybatis.spi.BaseDao;
import com.vteba.utils.id.ObjectId;
import com.vteba.utils.json.FastJsonUtils;
import com.wocai.jrt.admin.common.bean.Icon;
import com.wocai.jrt.admin.common.bean.Node;
import com.wocai.jrt.admin.common.bean.State;
import com.wocai.jrt.admin.common.cache.Const;
import com.wocai.jrt.admin.user.dao.RolesDao;
import com.wocai.jrt.admin.user.model.RoleAuth;
import com.wocai.jrt.admin.user.model.Roles;
import com.wocai.jrt.admin.user.model.RolesBean;
import com.wocai.jrt.admin.user.model.User;
import com.wocai.jrt.admin.user.model.UserRole;
import com.wocai.jrt.admin.user.service.spi.RoleAuthService;
import com.wocai.jrt.admin.user.service.spi.RolesService;
import com.wocai.jrt.admin.user.service.spi.UserRoleService;
import com.wocai.jrt.orgadmin.utils.UserUtils;

/**
 * 角色表相关的service业务实现。
 * @author yinlei
 * @date 2015-7-6 11:40:41
 */
@Named
public class RolesServiceImpl extends MyBatisServiceImpl<Roles, RolesBean, String> implements RolesService {
	private static final Logger LOGGER = LoggerFactory.getLogger(RolesServiceImpl.class);
	
	// 添加了方法后，记得改为private
	protected RolesDao rolesDao;
	
	@Inject
	private RoleAuthService roleAuthServiceImpl;
	
	@Inject
	private UserRoleService userRoleServiceImpl;
	
	@Override
	@Inject
	public void setBaseDao(BaseDao<Roles, RolesBean, String> rolesDao) {
		this.baseDao = rolesDao;
		this.rolesDao = (RolesDao) rolesDao;
	}

	@Override
	public int saveRoles(Roles roles) {
		String roleId = ObjectId.get().toString();
		roles.setRoleId(roleId);
		
		try {
			String authIds = roles.getAuthIds();
			LOGGER.info("权限ids=[{}]", authIds);
			
			roles.setCreateTime(new Date());
			roles.setRoleDesc(roles.getRoleName()); // 前端不传中文名，直接使用角色名
			roles.setPriority(2); // 2普通角色、1管理员角色
			int result = save(roles);
			if (result != 1) {
				return 0;
			}
			
			saveRolesAuth(roleId, authIds);
		} catch (Exception e) {
			LOGGER.error("save roles error, msg=[{}].", e.getMessage());
			throw new ServiceException("save roles error.", e);
		}
		return 1;
	}

	private void saveRolesAuth(String roleId, String authIds) {
		String[] authorityIds = StringUtils.split(authIds, ",");
		if (ArrayUtils.isEmpty(authorityIds)) {
			LOGGER.warn("role relation authorities is empty.");
		} else {
			LOGGER.info("start to save role and auth's relation.");
			for (String authId : authorityIds) {
				// 暂时这么判断
				if (authId.length() < Const.ID_LEN) {
					continue;
				}
				
				RoleAuth roleAuth = new RoleAuth();
				roleAuth.setId(ObjectId.get().toString());
				roleAuth.setAuthId(authId);
				roleAuth.setRoleId(roleId);
				
				int ret = roleAuthServiceImpl.save(roleAuth);
				if (ret != 1) {
					LOGGER.error("save role auth relation error.");
					throw new ServiceException("save role auth relation error.");
				}
			}
		}
	}

	@Override
	public int updateRoles(Roles roles) {
		String authIds = roles.getAuthIds();
		try {
			// 有角色和权限之间的关联，需要更新关联关系
			if (StringUtils.isNotBlank(authIds)) {
				int d = 0;
				if(roles.isUpdateAuth()){
					// 1、删除关联
					d = deleteRoleAuth(roles.getRoleId());
				}
				// 2、更新角色
				int u = updateById(roles);
				if (d > 0 && u <= 0) {
					LOGGER.error("delete relation success, but update roles record's number is 0.");
					throw new ServiceException("delete relation success, but update roles record's number is 0.");
				}
				// 3、维护角色和权限的新关联
				saveRolesAuth(roles.getRoleId(), authIds);
			} else { // 没有关联信息，直接更新角色信息
				int ret = updateById(roles);
				if (ret <= 0) { // 没有更新到数据，警告
					LOGGER.warn("update roles record's number is 0.");
				}
			}
		} catch (Exception e) {
			LOGGER.error("update roles error, msg=[{}].", e.getMessage());
			throw new ServiceException("update roles error", e);
		}
		return 1;
	}

	@Override
	public int deleteRoles(String roleId) {
		try {
			int ret = deleteRoleAuth(roleId);
			int result = deleteById(roleId);
			// 关联删除了，但是角色删除错误，回滚
			if (ret > 0 && result <= 0) {
				LOGGER.error("delete role and auth's relation success, but delete roles error.");
				throw new ServiceException("delete roles's relation error.");
			}
		} catch (Exception e) {
			LOGGER.error("delete roles error, roleId=[{}], msg=[{}].", roleId, e.getMessage());
			throw new ServiceException("delete roles error", e);
		}
		return 1;
	}

	/**
	 * 根据角色id删除，角色和权限的关联
	 * @param roleId 角色id
	 * @return 删除记录的条数
	 */
	private int deleteRoleAuth(String roleId) {
		RoleAuth roleAuth = new RoleAuth();
		roleAuth.setRoleId(roleId);
		int ret = roleAuthServiceImpl.deleteBulks(roleAuth);
		return ret;
	}

	@Override
	public Node getRoleTree(User user) {
		Node root = new Node();
		root.setId("-1");
		root.setText("用户角色");
		root.setIcon(Icon.BRIEF_WARN);
		try {
			// 以后缓存
			Roles roleParam = new Roles();
			roleParam.setOrgId(UserUtils.getOrgId());
			List<Roles> roleList = queryList(roleParam);
			Set<String> roleIdSet = new HashSet<String>();
			
			String userId = user.getId();
			if (userId != null && !userId.equals("null")) {
				// 获取该用户所有的角色ID
				UserRole params = new UserRole();
				params.setUserId(userId);
				List<UserRole> userRoleList = userRoleServiceImpl.queryList(params);
				for (UserRole bean : userRoleList) {
					roleIdSet.add(bean.getRoleId());
				}
				State state = new State();
				state.setOpened(true);
				root.setState(state);
			}
			
			List<Node> nodeList = new ArrayList<Node>();
			for (Roles role : roleList) {
				Node node = new Node();
				String roleId = role.getRoleId();
				if (roleIdSet.contains(roleId)) {
					State state = new State();
					state.setSelected(true);
					state.setLoaded(true);
					if (user.getEnable() != null && user.getEnable()) {
						state.setDisabled(true);
					}
					node.setState(state);
				} else {
					State state = new State();
					state.setLoaded(true);
					if (user.getEnable() != null && user.getEnable()) {
						state.setDisabled(true);
					}
					node.setState(state);
				}
				node.setId(roleId);
				node.setText(role.getRoleDesc()+"&nbsp;&nbsp;&nbsp;&nbsp;<button class=\"btn btn-sm btn-primary pull-right m-t-n-xs\"  name="+roleId+" onclick=\"checkRoles(this.name);\">查看角色权限</button>");
				node.setIcon(Icon.FILE_DANGER);
				node.setComMobile(role.getComMobile());
				node.setSecComfirm(role.isSecComfirm());
				nodeList.add(node);
			}
			root.setChildren(nodeList);
		} catch (Exception e) {
			LOGGER.error("get roles tree error, msg=[{}].", e.getMessage());
			throw new BasicException("get roles tree error.", e);
		}
		
		if (LOGGER.isInfoEnabled()) {
			LOGGER.info("tree json =[{}].", FastJsonUtils.toJson(root));
		}
		
		return root;
	}
}
